//
//  ActivityHomeController.swift
//  MoyoungHome
//
//  Created by 李然 on 2022/8/9.
//

import Foundation
import NSObject_Rx
import MYModule

import RxGesture
import SwiftDate
import UIKit
import JXSegmentedView

import RxSwift
import RxCocoa

typealias DFView = MYModule.View

class ActivityHomeController: BaseViewController {
    
    var provider: StepProvider?
    
    var viewModel = ActivityHomeViewModel()
    
    public var revealAll: Bool = true
    
    /// 是否显示right item
    public var showRightItem: Bool = true
    
    var selected: Int = 0 {
        
        didSet {
            
            dayDataView.isHidden = selected != 0
            weekDataView.isHidden = selected != 1
            monthDataView.isHidden = selected != 2
        }
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setNavitaionBar()
        
    }
    
    func setNavitaionBar() {
        
        self.navigation.bar.backgroundColor = UIColor.background
    
        navigation.bar.titleTextAttributes = [.foregroundColor: UIColor.assist_222222]
        navigation.bar.tintColor = UIColor.assist_222222
        
        //此处要做判断，本页面控制器是不是卡片的二级页面还是 Activity 的一级页面，二级页面的话就是返回按钮，一级页面就是标题
        
        if revealAll && self == self.navigationController?.children.first {
            
            
            let titleLabl = Label()
            titleLabl.textColor = UIColor.assist_222222
            titleLabl.font = Fonts.systemFont(ofSize: 20)
            titleLabl.text = "activity_title".language
            self.navigation.item.leftBarButtonItem = BarButtonItem(customView: titleLabl)
            
        } else {
            self.navigation.item.title = "activity_title".language
        }
        
        if showRightItem {
            
            let historyBtn = Button(type: .custom)
            historyBtn.setImage(UIImage(named: "ic_date")?.originalImageWithColor(color: UIColor.assist_000000), for: .normal)
            self.navigation.item.rightBarButtonItem = BarButtonItem(customView: historyBtn)
            
            
            historyBtn.rx.tap.subscribe(onNext: { [weak self] in
                guard let `self` = self else { return }
                let vc = CalendarController()
                vc.showType = .step24h
                vc.revealAll = self.revealAll
                vc.reloadRelay.subscribe(onNext: { [weak self] date in
                    guard let `self` = self else { return }
                    self.viewModel = ActivityHomeViewModel()
                    self.bindViewModel()
                }).disposed(by: self.rx.disposeBag)
                self.navigationController?.pushViewController(vc, animated: true)
            }).disposed(by: rx.disposeBag)
            
        }
        
        
    }
    
    override func makeUI() {
        super.makeUI()
        
        self.view.backgroundColor = UIColor.background
        
        
        segmentedView.commonConfig(backgroundColor: UIColor.background)
        segmentedView.dataSource = segmentedDataSource
        segmentedView.indicators = [indicator]
        
        let barChartConfig = DFBarChartViewConfig(xAxisLabelFont: Fonts.systemFont(ofSize: 11),
                                                  xAxisLabelTextColor: UIColor.assist_D0D0D0,
                                                  xAxisLineColor: UIColor.Step.theme)
        
        dayDataView.setChartConfig(barChartConfig)
        monthDataView.setChartConfig(barChartConfig)
        weekDataView.setChartConfig(barChartConfig)
        
        
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 20, right: 0)
        
        view.addSubview(scrollView)
        scrollView.addSubview(contentView)
        contentView.addSubview(segmentedView)
        contentView.addSubview(monthDataView)
        contentView.addSubview(weekDataView)
        contentView.addSubview(dayDataView)
        contentView.addSubview(pointView)
        contentView.bringSubviewToFront(pointView)
        
        segmentedView.isHidden = !revealAll
        weekDataView.isHidden = !revealAll
        monthDataView.isHidden = !revealAll
        
        
        scrollView.snp.makeConstraints { make in
            make.top.equalToSuperview().offset(kNavHeight)
            make.leading.trailing.bottom.equalToSuperview()
        }
        
        contentView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
            make.centerX.equalToSuperview()
        }
        
        
        segmentedView.snp.makeConstraints { make in
            make.top.leading.trailing.equalToSuperview()
            make.height.equalTo(70)
        }
        
        dayDataView.snp.makeConstraints { make in
            if self.revealAll {
                make.top.equalTo(segmentedView.snp.bottom)
            } else {
                make.top.equalToSuperview()
            }
            make.leading.trailing.equalToSuperview()
        }
        
        
        weekDataView.snp.makeConstraints { make in
            make.edges.equalTo(dayDataView)
        }
        
        
        monthDataView.snp.makeConstraints { make in
            make.edges.equalTo(dayDataView)
        }
        
        pointView.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.top.equalToSuperview().offset(self.revealAll ? 231.5 : 161.5)
            make.height.equalTo(140)
            make.width.equalTo(38)
        }
        
        
        if self.revealAll {
            
            contentView.addSubview(validExerciseView)
            contentView.addSubview(sevenDayReachView)
            contentView.addSubview(workoutsRecordsView)
            contentView.addSubview(beyondChartView)
            
            validExerciseView.snp.makeConstraints { make in
                make.top.equalTo(dayDataView.snp.bottom).offset(20)
                make.leading.trailing.equalToSuperview()
            }
            
            sevenDayReachView.snp.makeConstraints { make in
                make.top.equalTo(validExerciseView .snp.bottom).offset(20)
                make.leading.trailing.equalToSuperview()
            }
            
            
            workoutsRecordsView.snp.makeConstraints { make in
                make.top.equalTo(sevenDayReachView.snp.bottom).offset(20)
                make.leading.trailing.equalToSuperview()
            }
            
            beyondChartView.snp.makeConstraints { make in
                
                make.top.equalTo(workoutsRecordsView.snp.bottom).offset(20)
                make.leading.trailing.equalToSuperview()
                make.bottom.equalToSuperview()
            }
            
        } else {
            
            contentView.addSubview(sevenDayReachView)
            
            sevenDayReachView.snp.makeConstraints { make in
                make.top.equalTo(dayDataView.snp.bottom).offset(20)
                make.leading.trailing.equalToSuperview()
                make.bottom.equalToSuperview()
            }
        }
        
        self.pointView.pointColors = UIColor.Step.assist_slider
    }
    
    override func bindViewModel() {
        super.bindViewModel()
        

        var input = ActivityHomeViewModel.Input(viewWillAppear: self.rx.viewWillAppear)
        
        if let provider = provider {
            input.provider = provider
        }
        
        let output = self.viewModel.transform(input: input)
        
     
        output.dayChart.subscribe(onNext: { [weak self] viewModel in
            guard let viewModel = viewModel else { return }
            print(viewModel.dataSource)
            
            self?.dayDataView.bind(by: viewModel)
        }).disposed(by: rx.disposeBag)
        
        output.weekChart.subscribe(onNext: { [weak self] viewModel in
            guard let viewModel = viewModel else { return }
            self?.weekDataView.bind(by: viewModel)
        }).disposed(by: rx.disposeBag)
        
        output.montChart.subscribe(onNext: { [weak self] viewModel in
            guard let viewModel = viewModel else { return }
            
            self?.monthDataView.bind(by: viewModel)
        }).disposed(by: rx.disposeBag)
        
        
        output.totalTrainingTimes.subscribe(onNext: {[weak self] in
            
            self?.workoutsRecordsView.timesView.numLabel.text = $0.normalTitle
        }).disposed(by: rx.disposeBag)
        
        output.totalTrainingDurations.subscribe(onNext: {[weak self] in
            
            self?.workoutsRecordsView.durationView.numLabel.text = $0.normalTitle
        }).disposed(by: rx.disposeBag)
        
        output.totalTrainingCalories.subscribe(onNext: {[weak self] in
            
            self?.workoutsRecordsView.kcalView.numLabel.text = $0.normalTitle
            
        }).disposed(by: rx.disposeBag)
        
        output.workoutsRocords.subscribe(onNext: {[weak self] in
            
            self?.workoutsRecordsView.workoutsRecords = $0
            
        }).disposed(by: rx.disposeBag)
        
        
        output.compareDataSource.subscribe(onNext: { [weak self] result in
            guard let `self` = self else { return }
            
            let barHightLightColor = UIColor.Step.theme
            let barNormalColor = UIColor.Step.highlight
            
            self.beyondChartView.titleLabel.attributedText = self.titleAttributedText(result.percentage)
            self.beyondChartView.subTitleLabel.font = Fonts.systemFont(ofSize: 12)
            self.beyondChartView.subTitleLabel.textColor = UIColor.assist_A9A9A9
            self.beyondChartView.subTitleLabel.text = "activity_compare_male_users_content".language(with: [UserCacheManagement.userInfo().sex.localeName])
            
            self.beyondChartView.chartView.setConfig(self.config)
            self.beyondChartView.chartView.setXAxis(valueFormatter: self.valueFormatter)
            self.beyondChartView.chartView.setBarCount(7)
            
            var data: [Double] = []
            
            var index: Int?
            if result.percentage > 0 {
                index = result.index
                data = [100,80,75,60,50,40,30]
                
            } else {
                
                data = [0, 0, 0, 0, 0, 0, 0]
            }
            
            self.beyondChartView.chartView.setData(data,
                                                   barColor: barNormalColor,
                                                   barHighLichtColor: barHightLightColor, showEmpty: true)
            guard let index = index else {
                return
            }
 
            self.beyondChartView.chartView.showMarkerViewOfBar(index: index)
            
            
        }).disposed(by: rx.disposeBag)
        
        
        /// 天的滑动显示
        dayDataView.barChartView.selectIndex.asObservable().subscribe(onNext: {[weak self] i in
            
            guard let self = self, let model = output.providerRelay.value?.curDayStepRecord else { return }
            
            if i >= model.steps.count {
                self.dayDataView.timeLabel.text = model.date.localString
                return
            }
            
            let step = model.steps[i]
            self.dayDataView.timeLabel.text = model.date.localString
            self.dayDataView.dataLabel.text = step.normalTitle
            
        }).disposed(by: rx.disposeBag)
        
        /// 周的滑动显示
        weekDataView.barChartView.selectIndex.asObservable().subscribe(onNext: {[weak self] i in
            
            guard let self = self, let models = output.providerRelay.value?.weekRecord else { return }
            
            
            if i >= models.count {
                return
            }
            
            let model = models[i]
            let dateStr = model.date.localString
            
            self.showChart(self.weekDataView, dateStr: dateStr, step: model.step, distance: model.distance, calorie: model.calorie, secondTime: model.time)
            
        }).disposed(by: rx.disposeBag)
        
        /// 月的滑动显示
        monthDataView.barChartView.selectIndex.asObservable().subscribe(onNext: {[weak self] i in
            
            guard let self = self, let models = output.providerRelay.value?.monthRecord else { return }
            
            if i >= models.count {
                return
            }
            
            let model = models[i]
            let dateStr =  model.date.localString
            
            self.showChart(self.monthDataView, dateStr: dateStr, step: model.step, distance: model.distance, calorie: model.calorie, secondTime: model.time)
            
        }).disposed(by: rx.disposeBag)
        
        
        /// 滑动中
       pointView.rx.panGesture().when(.changed).subscribe(onNext: { [weak self] gesture in
            guard let `self` = self else { return }
            let point = gesture.location(in: self.view)
            
            self.dayDataView.slider(point)
            self.weekDataView.slider(point)
            self.monthDataView.slider(point)
            
            let w = self.pointView.width / 2 - 2
           
           if point.x < w || point.x > kScreenWidth - w {
               return
           }
            self.pointView.centerX = point.x
            
        }).disposed(by: rx.disposeBag)
        
        
        /// 滑动结束
        let sliderEnd = pointView.rx.panGesture().when(.ended).mapToVoid().asDriverOnErrorJustComplete().delay(.seconds(3))
        sliderEnd.asObservable().subscribe(onNext: { [weak self] _ in
            
            guard let self = self else { return }
            
            self.pointView.left = 0
            // 取消点击高亮，不然 = 0 的不显示
            self.dayDataView.clearHighlight()
            self.weekDataView.clearHighlight()
            self.monthDataView.clearHighlight()
            
            self.showAvg(provider: output.providerRelay.value)
            
        }).disposed(by: rx.disposeBag)
        
        // 日期更新
        output.providerRelay.subscribe(onNext: {[weak self] provider in
            
            guard let provider = provider else {
                return
            }
            
            self?.showAvg(provider: provider)
            
            let model = provider.curDayStepRecord
            self?.physicalActivity(of: model, weekModels: provider.weekRecord)
            
            self?.sevenDayReachView.date = model.date
            self?.sevenDayReachView.list = provider.sevenDaysRecord
            
        }).disposed(by: rx.disposeBag)
        
    }
    
    
    func showAvg(provider: StepProvider?) {
        
        if let model = provider?.curDayStepRecord {
            self.dayCahrtViewOf(day: model)
        }
        
        // 显示平均值
        let weekRecord = provider?.weekRecord
        let weekDateStr = weekRecord?.first?.date.localweekRangeString
        self.showChartAvg(self.weekDataView, models: weekRecord, dateStr: weekDateStr, showAvgUnit: true)
        
        let monthRecord = provider?.monthRecord
        let monthDateStr = monthRecord?.first?.date.localMonthRangeString
        self.showChartAvg(self.monthDataView, models: monthRecord, dateStr: monthDateStr, showAvgUnit: true)
        
    }
    
    
    /// 一天图表显示
    /// - Parameter model: model
    func dayCahrtViewOf(day model: ActivityModel) {
        
        dayDataView.timeLabel.text = model.date.localString
        dayDataView.dataLabel.text = model.step.normalTitle
        
        let tuple = Unit.sharedInstance.automationDistanceOf(Double(model.distance))
        dayDataView.distanceView.numLabel.text = tuple.distance.normalTitle
        dayDataView.distanceView.unitLabel.text = tuple.unitType.name
        
        dayDataView.kcalView.numLabel.text = model.calorie.normalTitle
        dayDataView.timeView.numLabel.text = (model.time/60).normalTitle
        
    }
    

    /// 图表显示平均值
    /// - Parameters:
    ///   - view: 图表
    ///   - models: models
    ///   - dateStr: 日期显示
    func showChartAvg(_ view: ActivityBarChartView?, models: [ActivityModel]?, dateStr: String?, showAvgUnit: Bool = false) {
        
        // 显示平均数
        var stepAvg = 0
        var distanceAvg = 0
        var calorieAvg = 0
        var secondTimeAvg = 0
        
        guard let models = models else {
            showChart(view, dateStr: dateStr, step: stepAvg, distance: distanceAvg, calorie: calorieAvg, secondTime: secondTimeAvg)
            
            return
        }

       let allModels = models.filter({ !$0.isEmpty })
        
        allModels.forEach { model in
            
            stepAvg += model.step
            distanceAvg += model.distance
            calorieAvg += model.calorie
            secondTimeAvg += model.time
            
        }
        if !allModels.isEmpty {
            stepAvg = stepAvg/allModels.count
            distanceAvg = distanceAvg/allModels.count
            calorieAvg = calorieAvg/allModels.count
            secondTimeAvg = secondTimeAvg/allModels.count
        }
        
        showChart(view, dateStr: dateStr, step: stepAvg, distance: distanceAvg, calorie: calorieAvg, secondTime: secondTimeAvg, showAvgUnit: showAvgUnit)
        
        
    }
    
    /// 图表显示
    /// - Parameters:
    ///   - view: 视图
    ///   - dateStr: 日期显示
    ///   - step: 步数
    ///   - distance: 距离
    ///   - calorie: 卡路里
    ///   - secondTime: 秒
    func showChart(_ view: ActivityBarChartView?, dateStr: String?, step: Int, distance: Int, calorie: Int, secondTime: Int, showAvgUnit: Bool = false) {
        
        view?.dataLabel.text = step.normalTitle
        view?.unitLabel.text = "unit_step".language
        view?.timeLabel.text = dateStr
        
        let tuple = Unit.sharedInstance.automationDistanceOf(Double(distance))
        
        view?.distanceView.numLabel.text = tuple.distance.normalTitle
        view?.distanceView.unitLabel.text = tuple.unitType.name
        
        view?.kcalView.numLabel.text = calorie.normalTitle
        view?.kcalView.unitLabel.text = "unit_calorie".language
        
        view?.timeView.numLabel.text = (secondTime/60).normalTitle
        view?.timeView.unitLabel.text = "unit_minute".language
        
        if showAvgUnit == true {
            
            view?.unitLabel.text = "unit_step".language + "/\("unit_everyday".language)"
            
            view?.distanceView.unitLabel.text = tuple.unitType.dayName
            view?.kcalView.unitLabel.text = "unit_calorie".language + "/\("unit_everyday".language)"
            view?.timeView.unitLabel.text = "unit_minute".language + "/\("unit_everyday".language)"
        }
        
    }
    
    /// 一周有效活动量
    /// - Parameter models: []
    func physicalActivity(of today: ActivityModel,  weekModels: [ActivityModel]) {
        
        
        // 一周平均有效时长
        self.validExerciseView.curWeekValidTime = weekModels.filter { $0.time >= 600 }.reduce(0, { $0 + $1.time })/60
        
        // 今日有效活动时长
        let todayTime = today.time/60
        self.validExerciseView.dataLabel.text = todayTime == 0 ? "--" : "\(todayTime)"
        
        var datas: [Double] = weekModels.map {
            return Double($0.time/60)
        }
        if datas.isEmpty {
            datas = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
        }
        
        let config = DFBarChartViewConfig.init(xAxisLabelFont: Fonts.systemFont(ofSize: 10),
                                               xAxisLabelTextColor: UIColor.assist_A9A9A9,
                                               xAxisLineColor: UIColor.Step.theme)
        self.validExerciseView.chartView.setConfig(config)
        self.validExerciseView.chartView.setXAxis(valueFormatter: WeekAxisValueFormatter())
        self.validExerciseView.chartView.setBarCount(7)
        
        self.validExerciseView.chartView.setData(datas, barColor: UIColor.Step.theme, barHighLichtColor: UIColor.Step.theme, showEmpty: true)
        
    }
    
    
    var config: DFBarChartViewConfig {
        
        let xAxisLabelColor = UIColor.Step.theme
        let xAxisLabelTextColor = UIColor.assist_A9A9A9
        
        let config = DFBarChartViewConfig.init(xAxisLabelFont: Fonts.systemFont(ofSize: 10),
                                               xAxisLabelTextColor: xAxisLabelTextColor,
                                               xAxisLineColor: xAxisLabelColor, highlightPerTapEnabled: false)
        return config
    }
    
    var valueFormatter: DataCompareAxisValueFormatter {
        let xAxisValues = ["0\n|\n3000","3001\n|\n6000","6001\n|\n9000","9001\n|\n12000","12001\n|\n15000","15001\n|\n18000","18001\n|\n∞"]
        return DataCompareAxisValueFormatter(axisValueArray: xAxisValues)
    }
    
    
    func titleAttributedText(_ percentage: Int) -> NSAttributedString {
        
        let percentStr = percentage == 0 ? "--%" : "\(percentage)%"
        let content = "activity_compare_other_people_run_content".language(with: [percentStr])
        
        return content.toAttributed
            .foregroundColor(UIColor.assist_222222)
            .font(Fonts.boldSystemFont(ofSize: 16))
            .font(Fonts.boldSystemFont(ofSize: 20), range: (content as NSString).range(of: percentStr))
            .rawValue
        
    }
    
    
    //MARK: - lazy load -
    lazy var scrollView: ScrollView = {
        let view = ScrollView()
        view.showsVerticalScrollIndicator = false
        view.backgroundColor =  UIColor.darkBackground
        view.bounces = false
        return view
    }()
    
    lazy var contentView: DFView = {
        let view = DFView()
        view.backgroundColor =  UIColor.darkBackground
        return view
    }()
    
    lazy var segmentedView: JXSegmentedView = {
        let segmentedView = JXSegmentedView()
        segmentedView.delegate = self
        
        return segmentedView
    }()
    
    lazy var indicator: JXSegmentedIndicatorBackgroundView = {
        let indicator = JXSegmentedIndicatorBackgroundView()
        
        indicator.commonConfig(indicatorColor: UIColor.Step.theme, shadowColor: UIColor.Step.theme)
        
        return indicator
    }()
    
    lazy var segmentedDataSource: JXSegmentedTitleDataSource = {
        let datasource = JXSegmentedTitleDataSource()
        
        datasource.commonConfig(titles: ["activity_day_title".language, "activity_week_title".language, "activity_month_title".language])
        
        
        return datasource
    }()
    
    lazy var dayDataView: ActivityBarChartView = {
        let view = ActivityBarChartView.init(frame: .zero)
        view.backgroundColor = UIColor.background
        view.barClolr = UIColor.Step.theme
        view.barHighLichtColor = UIColor.Step.highlight
        view.timeTextColor = UIColor.assist_222222
        view.unitTextColor = UIColor.assist_222222
        view.dataTextColor = UIColor.assist_222222
        
        view.cornerRadius = 18.0
        return view
    }()
    
    lazy var weekDataView: ActivityBarChartView = {
        let view = ActivityBarChartView.init(frame: .zero)
        view.backgroundColor = UIColor.background
        view.barClolr = UIColor.Step.theme
        view.barHighLichtColor = UIColor.Step.highlight
        view.timeTextColor = UIColor.assist_222222
        view.unitTextColor = UIColor.assist_222222
        view.dataTextColor = UIColor.assist_222222
        
        view.distanceView.unitLabel.text = "activity_unit_km_day".language
        view.kcalView.unitLabel.text = "unit_calorie".language
        view.timeView.unitLabel.text = "unit_minute".language
        
        
        view.cornerRadius = 18.0
        return view
    }()
    
    lazy var monthDataView: ActivityBarChartView = {
        let view = ActivityBarChartView.init(frame: .zero)
        view.backgroundColor = UIColor.background
        view.barClolr = UIColor.Step.theme
        view.barHighLichtColor = UIColor.Step.highlight
        view.timeTextColor = UIColor.assist_222222
        view.unitTextColor = UIColor.assist_222222
        view.dataTextColor = UIColor.assist_222222
        
        
        view.distanceView.unitLabel.text = "activity_unit_km_day".language
        view.kcalView.unitLabel.text = "unit_calorie".language
        view.timeView.unitLabel.text = "unit_minute".language
        
        
        view.cornerRadius = 18.0
        return view
    }()
    
    lazy var pointView: DataPointView = {
        let view = DataPointView()
        view.imgColor = UIColor.assist_FFFFFF
        return view
    }()
    
    lazy var distanceView: ActivityDataIconCell = {
        let view = ActivityDataIconCell.init()
        
        return view
    }()
    
    lazy var kcalView: ActivityDataIconCell = {
        let view = ActivityDataIconCell.init()
        view.iconView.image = UIImage(named: "ic_home_today_steps_calorie")
        return view
    }()
    
    lazy var timeView: ActivityDataIconCell = {
        let view = ActivityDataIconCell.init()
        view.iconView.image = UIImage(named: "ic_home_today_steps_duration")
        return view
    }()
    
    lazy var validExerciseView: ActivityValidExerciseView = {
        let view = ActivityValidExerciseView.init()
        view.curWeekValidTime = 0
        view.cornerRadius = 18.0
        view.chartView.highlightFullBarEnabled = true
        return view
    }()
    
    lazy var sevenDayReachView: ActivityGoalsOfLastSevenDaysView = {
        let view = ActivityGoalsOfLastSevenDaysView.init()
        
        view.cornerRadius = 18.0
        return view
    }()
    
    private lazy var workoutsRecordsView: ActivityWorkoutsRecordsView = {
        let view = ActivityWorkoutsRecordsView()
        view.cornerRadius = 18.0
        return view
    }()
    
    lazy var beyondChartView: BarRoundChartView = {
        let view = BarRoundChartView()
        view.backgroundColor = UIColor.background
        view.cornerRadius = 18.0
        view.chartHeight = 150
        return view
    }()
    
    
    
}

extension ActivityHomeController: JXSegmentedViewDelegate {
    
    func segmentedView(_ segmentedView: JXSegmentedView, didClickSelectedItemAt index: Int) {
        
        self.selected = index
    }
    
    
}
